/*******************************************************************************
 * Copyright (c) 2017 I3S laboratory, INRIA and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     I3S laboratory and INRIA Kairos - initial API and implementation
 *******************************************************************************/
/*
 * generated by Xtext
 */
package org.eclipse.gemoc.execution.moccml.testscenariolang.xtext.scoping;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.gemoc.execution.moccml.testscenariolang.model.TestScenarioLang.Scenario;
import org.eclipse.gemoc.execution.moccml.testscenariolang.model.TestScenarioLang.RewritingRuleCallStatement;
import org.eclipse.gemoc.execution.moccml.testscenariolang.model.TestScenarioLang.TestScenarioLangPackage;
import org.eclipse.gemoc.execution.moccml.testscenariolang.model.TestScenarioLang.ObjectVariable;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.JvmVisibility;
import org.eclipse.xtext.common.types.TypesPackage;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.FilteringScope;
import org.eclipse.xtext.scoping.impl.SimpleScope;

import com.google.common.base.Predicate;

import fr.inria.aoste.timesquare.ccslkernel.model.TimeModel.CCSLModel.ClockExpressionAndRelation.Relation;

/**
 * This class contains custom scoping description.
 * 
 * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping
 * on how and when to use it 
 *
 */
public class TestScenarioLangScopeProvider extends AbstractDeclarativeScopeProvider {
		
	@Override
	public IScope getScope(final EObject context, EReference reference) {
		if (context instanceof RewritingRuleCallStatement
				&& reference == TestScenarioLangPackage.Literals.REWRITING_RULE_CALL_STATEMENT__METHOD) {
			return scope_CodeExecutionBehavior_method((RewritingRuleCallStatement) context, reference);
		}
//		else if (context instanceof CodeExecRelationBehavior
//					&& reference == CodeExecutionPackage.eINSTANCE.getCodeExecRelationBehavior_Relation()) {
//			IScope scope = delegateGetScope(context, reference);
//			Predicate<IEObjectDescription> predicate = new NotAnAssertionPredicate();
//			IScope filteredScope = new FilteringScope(scope, predicate);			
//			return filteredScope;
//		}
//		else if (context instanceof CodeExecAssertionBehavior
//					&& reference == CodeExecutionPackage.eINSTANCE.getCodeExecAssertionBehavior_Assertion()) {
//			IScope scope = delegateGetScope(context, reference);;
//			Predicate<IEObjectDescription> predicate = new IsAnAssertionPredicate();
//			IScope filteredScope = new FilteringScope(scope, predicate);			
//			return filteredScope;
//		}
		else if ( reference == TypesPackage.Literals.JVM_ANY_TYPE_REFERENCE__TYPE ) {
			IScope scope = delegateGetScope(context, reference);
			return scope;
		}
		return super.getScope(context, reference);
	}

	private IScope scope_CodeExecutionBehavior_method(RewritingRuleCallStatement ctx, EReference ref) {
		ObjectVariable variable = ctx.getObjectVariable();
		List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
		if (variable != null) {
			JvmTypeReference typeRef = ctx.getObjectVariable().getType();
			if (typeRef != null) {
				JvmType type = typeRef.getType();
				if (type != null) {
					if (type instanceof JvmGenericType) {
						for (JvmOperation operation : ((JvmGenericType) type).getDeclaredOperations()) {
							// Only accept public methods
							if (operation.getVisibility() == JvmVisibility.PUBLIC
									/*&& operation.getParameters().isEmpty()*/) {
								descriptions.add(EObjectDescription.create(QualifiedName.create(operation.getSimpleName()),
										operation));
							}
						}
					}
				}
			}
		}
		return new SimpleScope(descriptions);
	}
//		
//	private final class NotAnAssertionPredicate implements Predicate<IEObjectDescription> {
//		@Override
//		public boolean apply(IEObjectDescription input) {
//			final EObject inputEObject= input.getEObjectOrProxy();
//			if (inputEObject instanceof Relation) {
//				return  ! ((Relation)inputEObject).getIsAnAssertion();
//			}
//			return false;
//		}
//	}
//
//	private final class IsAnAssertionPredicate implements Predicate<IEObjectDescription> {
//		@Override
//		public boolean apply(IEObjectDescription input) {
//			final EObject inputEObject= input.getEObjectOrProxy();
//			if (inputEObject instanceof Relation) {
//				return ((Relation)inputEObject).getIsAnAssertion();
//			}
//			return false;
//		}
//	}
	
}
